let _Vue = null
export default class VueRouter {
    // 静态方法， 注意参数是 Vue构造器
    static install(Vue){
        // 1. 判断是否已经被注册过（单例模式）
        if(VueRouter.install.installed){
            return // 啥也不做
        }
        VueRouter.install.installed = true

        // 2. 将 Vue 构造器 放到全局环境，以后给其他功能用
        _Vue = Vue

        // 3. 将 Vue 实例化时 传入的 router 对象注入到每一个 vue 实例上
       _Vue.mixin({
            beforeCreate () {
                if (this.$options.router) {
                    _Vue.prototype.$router = this.$options.router
                }
            }
       })

    }

    constructor(options){
        this.options = options
        this.routeMap = {}
        // data 保存当前应用路由， 必须是响应式的，才能让视图自动响应渲染
        this.data = _Vue.observable({
            // 默认是 / 首页
            // this.data.current = window.location.pathname
            current: this.initCurrentPath(options.mode)
        })
    }

    init(Vue){
        this.createRouteMap()
        this.initEvent()
        this.initComponents(Vue)
    }

    createRouteMap () {
        // 遍历所有的路由规则，把路由规则解析成键值对的形式 存储到routeMap中
        this.options.routes.forEach(route => {
            this.routeMap['#' + route.path] = route.component
        })
    }

    initComponents (Vue) {
        Vue.component('router-link', {
            props: {
                to: String
            },
            render (h) {
                return h('a', {
                    attrs: {
                        href: '#' + this.to
                    },
                }, [this.$slots.default])
            },
        })

        const self = this;
        Vue.component('router-view', {
            render (h) {
                // 当前路由组件，找不到时返回 404 组件
                const component = self.routeMap[self.data.current] || self.routeMap['#*']
                return h(component)
            }
        })
    }

    initEvent () {
        // 初始化时，将 hash 地址，也就是 包括#以及后面的地址 存储到 this.data.current
        this.data.current = window.location.hash
        // 监听 hashchange 事件，hash 改变时更新 this.data.current
        window.addEventListener('hashchange', () => {
            this.data.current = window.location.hash
        })
    }
}